package mn.idax.exchange.otc.web;

import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import mn.idax.exchange.auth.bean.AuthInfo;
import mn.idax.exchange.auth.exception.IdaxException;
import mn.idax.exchange.auth.interfaces.AuthService;
import mn.idax.exchange.auth.util.AuthInfoUtils;
import mn.idax.exchange.auth.util.RSAEncrypt;
import mn.idax.exchange.common.bean.ResponseData;
import mn.idax.exchange.otc.constant.RequestUrlConstant;
import mn.idax.exchange.otc.domain.OTCBeneficiarysInfoRequest;
import mn.idax.exchange.otc.domain.OTCBeneficiarysRequest;
import mn.idax.exchange.otc.domain.openapi.*;
import mn.idax.exchange.otc.entity.OTCBeneficiarys;
import mn.idax.exchange.otc.entity.User;
import mn.idax.exchange.otc.enums.OTCBeneficiarysEnum;
import mn.idax.exchange.otc.enums.TimeUnitEnum;
import mn.idax.exchange.otc.enums.response.OTCAdResponseEnum;
import mn.idax.exchange.otc.enums.response.OTCBeneficiarysResponseEnum;
import mn.idax.exchange.otc.enums.response.OrderResponseEnum;
import mn.idax.exchange.otc.enums.response.UserResponseEnum;
import mn.idax.exchange.otc.mapper.OTCOrderMapper;
import mn.idax.exchange.otc.service.*;
import mn.idax.exchange.otc.util.DateUtils;
import mn.idax.exchange.otc.util.FileUtils;
import mn.idax.exchange.otc.util.LogUtils;
import mn.idax.exchange.otc.vo.BeneficiarysInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Api(value = "openApi", tags = {"openApi"})
@RequestMapping(RequestUrlConstant.MODULE_OPEN)
@RestController
public class OpenApiController extends BaseController {

    @Autowired
    OpenApiService openApiService;
    @Autowired
    OTCOrderMapper otcOrderMapper;

    @Autowired
    private OTCBeneficiarysService otcBeneficiarysService;

    @Autowired
    private UserService userService;

    @Autowired
    private OTCSysDictionaryItemService otcSysDictionaryItemService;

    @Autowired
    private AuthService authService;

    @Autowired
    private FileUrlService fileUrlService;

    /**
     * 用户同步
     */
    @ApiOperation(value = "用户同步")
    @RequestMapping(value = RequestUrlConstant.OPEN_PRIVATE + "/userSync", method = RequestMethod.POST)
    public ResponseData userSync(@RequestBody UserSyncRequest userSyncRequest) throws IdaxException {
        // 非空判断
        if (userSyncRequest.getUserId() == null ||
                StringUtils.isEmpty(userSyncRequest.getCertificateNo()) ||
                StringUtils.isEmpty(userSyncRequest.getMobile()) ||
                StringUtils.isEmpty(userSyncRequest.getPassword())) {
            return ResponseData.error(OTCAdResponseEnum.LACK_REQUEST_PARAMTER.getCode(), "");
        }
        userSyncRequest.setPassword(userSyncRequest.getPassword());
        return openApiService.userSync(userSyncRequest);
    }

    /**
     * 修改资金
     */
    @ApiOperation(value = "修改资金")
    @RequestMapping(value = RequestUrlConstant.OPEN_PRIVATE + "/changeAccount", method = RequestMethod.POST)
    public ResponseData changeAccount(@RequestBody ChangeAccountRequest changeListData) {
        // 非空判断
        if (changeListData.getUserId() == null || changeListData.getCoinId() == null) {
            return ResponseData.error(OTCAdResponseEnum.LACK_REQUEST_PARAMTER.getCode(), "");
        }
        if (changeListData.getAvailableChange() == null || changeListData.getAvailableChange().compareTo(BigDecimal.ZERO) != 1) {
            return ResponseData.error(OrderResponseEnum.ORDER_QTYISERROR.getRespCode(), "");
        }

        return openApiService.changeAccount(changeListData);
    }

    /**
     * 登录同步
     */
    @ApiOperation(value = "登录同步")
    @RequestMapping(value = RequestUrlConstant.OPEN_PRIVATE + "/loginSync", method = RequestMethod.POST)
    public ResponseData loginSync(@RequestBody LoginSyncRequest loginSyncRequest) {
        // 非空判断
        if (loginSyncRequest.getUserId() == null || loginSyncRequest.getExpireHour() <= 0) {
            return ResponseData.error(OTCAdResponseEnum.LACK_REQUEST_PARAMTER.getCode(), "");
        }
        if (loginSyncRequest.getUserSourceCode() == null) {
            loginSyncRequest.setUserSourceCode(1);
        }

        return openApiService.loginSync(loginSyncRequest);
    }

    /**
     * 登出同步
     */
    @ApiOperation(value = "登出同步")
    @RequestMapping(value = RequestUrlConstant.OPEN_PRIVATE + "/logoutSync", method = RequestMethod.POST)
    public ResponseData logoutSync(@RequestBody LoginSyncRequest loginSyncRequest) {
        // 非空判断
        if (loginSyncRequest.getUserId() == null) {
            return ResponseData.error(OTCAdResponseEnum.LACK_REQUEST_PARAMTER.getCode(), "");
        }
        if (loginSyncRequest.getUserSourceCode() == null) {
            loginSyncRequest.setUserSourceCode(1);
        }

        return openApiService.logoutSync(loginSyncRequest);
    }

    /**
     * 获取修改资金记录
     */
    @ApiOperation(value = "获取修改资金记录")
    @RequestMapping(value = RequestUrlConstant.OPEN_PUBLIC_T + "/queryChangeAccountLog", method = RequestMethod.POST)
    public ResponseData queryChangeAccountLog(@RequestBody ChangeAccountLogRequest changeAccountLogRequest) {
        // 非空判断
        if (changeAccountLogRequest.getPageIndex() == null || changeAccountLogRequest.getPageSize() == null) {
            return ResponseData.error(OTCAdResponseEnum.LACK_REQUEST_PARAMTER.getCode(), "");
        }
        if (changeAccountLogRequest.getPageSize() > 1000) {
            changeAccountLogRequest.setPageIndex(1000);
        }

        changeAccountLogRequest.setUserId(getUserId());
        changeAccountLogRequest.setType(33);

        return ResponseData.success(openApiService.queryChangeAccountLog(changeAccountLogRequest));
    }


    /**
     * 获取修改资金记录
     */
    @ApiOperation(value = "获取用户资金")
    @RequestMapping(value = RequestUrlConstant.OPEN_PUBLIC_T + "/getBalance", method = RequestMethod.POST)
    public ResponseData getBalance(@RequestBody GetBalanceRequest getBalanceRequest) {
        getBalanceRequest.setUserId(getUserId());
        return ResponseData.success(openApiService.getBalance(getBalanceRequest));
    }


    /**
     * 获取成交价格走势
     */
    @ApiOperation(value = "获取成交价格走势")
    @RequestMapping(value = RequestUrlConstant.OPEN_PUBLIC + "/getFinalPriceTrendChart", method = RequestMethod.POST)
    public ResponseData getFinalPriceTrendChart(@RequestBody GetFinalPriceTrendChartReq getFinalPriceTrendChartReq) {
        if (getFinalPriceTrendChartReq.getCount() < 1 || getFinalPriceTrendChartReq.getCount() > 1440 || StringUtils.isEmpty(getFinalPriceTrendChartReq.getTimeUnit())) {
            return ResponseData.error(OTCAdResponseEnum.LACK_REQUEST_PARAMTER.getCode(), "");
        }
        TimeUnitEnum millisecond = TimeUnitEnum.getMillisecond(getFinalPriceTrendChartReq.getTimeUnit());
        if (millisecond == null) {
            return ResponseData.error(OTCAdResponseEnum.LACK_REQUEST_PARAMTER.getCode(), "");
        }
        if (getFinalPriceTrendChartReq.getEndTime() == null) {
            getFinalPriceTrendChartReq.setEndTime(System.currentTimeMillis());
        }
        List<TrendChartDTO> trendChartDTOS = Lists.newArrayList();

        long startMs = getFinalPriceTrendChartReq.getEndTime() - (millisecond.getMillisecond() * getFinalPriceTrendChartReq.getCount());
        Date statTime = new Date(startMs);
        Date endTime = new Date(getFinalPriceTrendChartReq.getEndTime());
        List<FinalPriceTrendChartDTO> finalPriceTrendChart = otcOrderMapper.getFinalPriceTrendChart(statTime, endTime, millisecond.getFormat().length());
        if (finalPriceTrendChart.isEmpty()) {
            return ResponseData.success(trendChartDTOS);
        }
        // 时间转时间戳
        for (FinalPriceTrendChartDTO finalPriceTrendChartDTO : finalPriceTrendChart) {
            trendChartDTOS.add(new TrendChartDTO(DateUtils.getDate(finalPriceTrendChartDTO.getDatetime(), millisecond.getFormat()).getTime(), finalPriceTrendChartDTO.getPrice()));
        }
        Map<Long, TrendChartDTO> trendChartDTOMap = trendChartDTOS.stream().collect(Collectors.toMap(TrendChartDTO::getDatetime, trendChartDTO -> trendChartDTO));
        Long curMs = DateUtils.getDate(startMs, millisecond.getFormat()).getTime();
        TrendChartDTO lastPrice = trendChartDTOS.get(0);
        trendChartDTOS.clear();
        while (curMs <= endTime.getTime()) {
            TrendChartDTO trendChartDTO = trendChartDTOMap.get(curMs);
            if (Objects.isNull(trendChartDTO)) {
                trendChartDTOS.add(new TrendChartDTO(curMs, lastPrice.getPrice()));
            } else {
                trendChartDTOS.add(new TrendChartDTO(curMs, trendChartDTO.getPrice()));
                lastPrice = trendChartDTO;
            }
            curMs += millisecond.getMillisecond();
        }

        return ResponseData.success(trendChartDTOS);
    }


    /**
     * 获取用户的收款账号信息列表
     *
     * @param request
     * @throws Exception
     */
    @ApiOperation(value = "获取用户的收款账号信息列表", notes = "获取用户的收款账号信息列表")
    @RequestMapping( value = RequestUrlConstant.OPEN_PUBLIC_T + "/beneficiarys/list", method = RequestMethod.POST)
    public ResponseData list(@RequestBody GetOTCBeneficiarysRequest getOTCBeneficiarysRequest) throws Exception {
        // 获取登录用户信息
        Integer userId =getUserId();//  getOTCBeneficiarysRequest.getUserId();//
        List<BeneficiarysInfo> list = otcBeneficiarysService.selectPayTypeInfoByUserID(userId);
        return ResponseData.success(list);
    }

    /**
     * 根据id获取用户的收款账号信息
     *
     * @param request
     * @throws Exception
     */
    @ApiOperation(value = "根据id获取用户的收款账号信息", notes = "根据id获取用户的收款账号信息")
    @RequestMapping(value = RequestUrlConstant.OPEN_PUBLIC_T + "/beneficiarys/info", method = RequestMethod.POST)
    public ResponseData info(@RequestBody GetOTCBeneficiarysInfoRequest getOTCBeneficiarysInfoRequest, HttpServletRequest request) throws Exception {
        //检查id
        if (getOTCBeneficiarysInfoRequest.getId() == null || getOTCBeneficiarysInfoRequest.getId() < 1) {
            throw new mn.idax.exchange.otc.exception.IdaxException(OTCBeneficiarysResponseEnum.ID_NOT_EXIST.getCode());
        }

        // 获取登录用户信息
        Integer userId = getUserId();// getOTCBeneficiarysInfoRequest.getUserId();//

        OTCBeneficiarys otcBeneficiarys = otcBeneficiarysService.selectByPrimaryKey(getOTCBeneficiarysInfoRequest.getId());
        if (otcBeneficiarys == null || !otcBeneficiarys.getUserid().equals(userId)) {
            throw new mn.idax.exchange.otc.exception.IdaxException(OTCBeneficiarysResponseEnum.DATA_NOT_EXIST.getCode());
        }
        //不返回用户的id
        otcBeneficiarys.setUserid(null);
        otcBeneficiarys.setAttachmenturl(fileUrlService.dealFileUrlAddress(otcBeneficiarys.getAttachmenturl()));
        return ResponseData.success(otcBeneficiarys);
    }


    /**
     * 创建收款账号信息
     *
     * @param beneficiarysRequest
     * @param request
     * @throws Exception
     */
    @ApiOperation(value = "创建收款账号信息", notes = "创建收款账号信息")
    @RequestMapping( value = RequestUrlConstant.OPEN_PUBLIC_T + "/beneficiarys/create", method = RequestMethod.POST)
    public ResponseData create(@Valid @RequestBody OTCBeneficiarysRequest beneficiarysRequest) throws Exception {

        if (!StringUtils.isEmpty(beneficiarysRequest.getAttachmenturl())){
            String attachmenturl = fileUrlService.subFilePath(beneficiarysRequest.getAttachmenturl());
            beneficiarysRequest.setAttachmenturl(attachmenturl);
            LogUtils.info(this.getClass(), "create attachmenturl " + attachmenturl);
        }

        //检查文件格式是否合法
        if (OTCBeneficiarysEnum.PayMethodEnum.TYPE_WEIXIN.getCode().equals(beneficiarysRequest.getDictitemid())
                && !FileUtils.isImage(beneficiarysRequest.getAttachmenturl())) {
            throw new mn.idax.exchange.otc.exception.IdaxException(OTCBeneficiarysResponseEnum.UPLOAD_FILE_TYPE_ILLEGAL.getCode());
        }

        //收款名称必传
//    	 if (StringUtils.isEmpty(beneficiarysRequest.getName())){
//			 throw new IdaxException(OTCBeneficiarysResponseEnum.ACCOUNT_NAME_NOT_NULL.getCode());
//		 }

//        String privateKey = authService.getPrivateKey();
//        String account = RSAEncrypt.decrypt(beneficiarysRequest.getAccount(),privateKey);
//        LogUtils.info(this.getClass(),"decrypt account is " + account);
//        beneficiarysRequest.setAccount(account);
//        //zhagnhu 和收款名称长度
//        if (account.length() > 25 || beneficiarysRequest.getName().length() > 25) {
//            throw new mn.idax.exchange.otc.exception.IdaxException(OTCBeneficiarysResponseEnum.EXCEEDED_LENGTH_LIMIT.getCode());
//        }

        //收款类型是银行卡时，银行名称与支行名称必传
        if (OTCBeneficiarysEnum.PayMethodEnum.TYPE_BANK.getCode().equals(beneficiarysRequest.getDictitemid())) {
            if (StringUtils.isBlank(beneficiarysRequest.getBankname())) {
                throw new mn.idax.exchange.otc.exception.IdaxException(OTCBeneficiarysResponseEnum.BANK_NAME_NOT_NULL.getCode());
            }
            if (beneficiarysRequest.getBankname().length() > 25 || beneficiarysRequest.getSubbranchbankname().length() > 25) {
                throw new mn.idax.exchange.otc.exception.IdaxException(OTCBeneficiarysResponseEnum.EXCEEDED_LENGTH_LIMIT.getCode());
            }
        }



        // 获取登录用户信息
        Integer userId =getUserId();//  beneficiarysRequest.getUserid();//

//        //判断用户是否实名 未实名不能添加
        User user = userService.getUserById(userId);
//        /***登录密码验证**/
//        boolean result = verifyPassword(beneficiarysRequest.getPassword(), user);
//        if(!result){
//            throw new mn.idax.exchange.otc.exception.IdaxException(UserResponseEnum.USER_PASSWORD_ERROR.getRespCode());
//        }
//
//        if (!user.getIscertificate()) {
//            throw new mn.idax.exchange.otc.exception.IdaxException(UserResponseEnum.USER_NOT_CERTIFICATE.getRespCode());
//        }

        if (beneficiarysRequest.getId() == null || beneficiarysRequest.getId().intValue() == 0) {
            //检查用户是否已绑定相应的账号信息，限制一种收款类型只能绑定一张
            List<OTCBeneficiarys> list = otcBeneficiarysService.selectByUserID(userId);
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    if (list.get(i).getDictitemid().equals(beneficiarysRequest.getDictitemid())) {
                        throw new mn.idax.exchange.otc.exception.IdaxException(OTCBeneficiarysResponseEnum.TRANSACTION_MODE_ALREADY_EXISTED.getCode());
                    }
                }
            }

            OTCBeneficiarys otcBeneficiarys = new OTCBeneficiarys();
            BeanUtils.copyProperties(beneficiarysRequest, otcBeneficiarys);

            Date currDate = DateUtils.getUTCNow();
            //id为自增字段
            otcBeneficiarys.setId(null);
            LogUtils.info(this.getClass(), "This user Surname is ****** " + user.getSurname() + "Name is ******" + user.getName());
            otcBeneficiarys.setName(beneficiarysRequest.getName());
            otcBeneficiarys.setCreatetime(currDate);
            otcBeneficiarys.setUpdatetime(currDate);
            otcBeneficiarys.setUserid(userId);
            //设置默认显示
            otcBeneficiarys.setIsdisplay(true);

            //支付宝默认
            if (OTCBeneficiarysEnum.PayMethodEnum.TYPE_BANK.getCode().equals(beneficiarysRequest.getDictitemid())) {
                otcBeneficiarys.setIsdefault(true);
            }

            //支付宝与微信收款方式不需要填写此字段，默认赋值成account字段
//            if(StringUtils.isBlank(otcBeneficiarys.getName())) {
//            	otcBeneficiarys.setName(otcBeneficiarys.getAccount());
//            }

            otcBeneficiarysService.addOTCBeneficiarys(otcBeneficiarys);
        } else {
            update(beneficiarysRequest, user);
        }
        return ResponseData.success();
    }

    /**
     * @throws
     * @Title: update
     * @Description: 修改收款账号信息
     * @param: @param beneficiarysRequest
     * @param: @return
     * @param: @throws Exception
     * @return: ResponseData
     */
    private ResponseData update(OTCBeneficiarysRequest beneficiarysRequest, User user) throws Exception {
        // 获取登录用户信息
        AuthInfo authInfo = AuthInfoUtils.getCurrent();
        Integer userId = Optional.ofNullable(authInfo).map(a -> a.getId()).orElse(-1);

        //检查是否属于该用户的收款交易方式
        OTCBeneficiarys otcBeneficiarys = otcBeneficiarysService.selectByPrimaryKey(beneficiarysRequest.getId());
        if (otcBeneficiarys != null && otcBeneficiarys.getUserid().equals(userId)) {

            //收款类型是银行卡时，银行名称与支行名称必传
//		   if(OTCBeneficiarysEnum.type_bank.getCode().equals(otcBeneficiarys.getDictitemid())) {
//			   if(StringUtils.isBlank(beneficiarysRequest.getBankname())) {
//			       throw new IdaxException(OTCBeneficiarysResponseEnum.BANK_NAME_NOT_NULL.getCode());
//			   }
//		   }

            //创建对象
            OTCBeneficiarys newOTCBeneficiarys = new OTCBeneficiarys();
            BeanUtils.copyProperties(beneficiarysRequest, newOTCBeneficiarys);
            newOTCBeneficiarys.setId(otcBeneficiarys.getId());
            newOTCBeneficiarys.setName(beneficiarysRequest.getName());
            newOTCBeneficiarys.setUpdatetime(DateUtils.getUTCNow());
            //修改时不能修改收款类型
            newOTCBeneficiarys.setDictitemid(otcBeneficiarys.getDictitemid());
            //设置默认显示
//            newOTCBeneficiarys.setIsdisplay(true);

            //支付宝与微信收款方式不需要填写此字段，默认赋值成account字段
//		 if(StringUtils.isBlank(newOTCBeneficiarys.getName())) {
//			   newOTCBeneficiarys.setName(newOTCBeneficiarys.getAccount());
//		 }

            otcBeneficiarysService.updateOTCBeneficiarys(newOTCBeneficiarys);
        } else {
            throw new mn.idax.exchange.otc.exception.IdaxException(OTCBeneficiarysResponseEnum.DATA_NOT_EXIST.getCode());
        }
        return ResponseData.success();
    }


}
